package main

import "fmt"

/*
*
第二遍参考了答案的缩容思路，把一开始的结构体删除了，直接对slice进行修改就行了（还是没有完全习惯这种方式）
*/
const (
	MinCap     = 64
	ShrinkRate = 0.75
)

func Delete[T any](slice []T, index int) ([]T, error) {
	if index < 0 || index >= len(slice) {
		return slice, fmt.Errorf("index out of the size of slice")
	}
	copy(slice[index:], slice[index+1:])
	slice = slice[:len(slice)-1]
	return shrink(slice), nil
}

func shrink[T any](src []T) []T {
	l, c := len(src), cap(src)
	c, changed := capCalculate(l, c)
	if !changed {
		return src
	}
	newSlice := make([]T, l, c)
	newSlice = append(newSlice, src...)
	return newSlice
}

func capCalculate(l int, c int) (newCap int, isChanged bool) {
	if c <= MinCap {
		return c, false
	}
	if c >= 2048 && c/l >= 2 {
		return int(float32(c) * float32(ShrinkRate)), true
	}
	if c < 2048 && c/l >= 4 {
		return c / 2, true
	}
	return c, false
}
func main() {
	testLen := 100
	testCap := 4096
	testIndexToDelete := testLen / 10
	testSlice := make([]int64, testLen, testCap)
	for i := 0; i < testLen; i++ {
		testSlice[i] = int64(i)
	}
	newSlice, err := Delete(testSlice, testIndexToDelete)
	if err != nil {
		fmt.Printf("error:%v", err)
	}
	fmt.Printf("slice after delete: len: %v\tcap:%v", len(newSlice), cap(newSlice))
}
